package com.ease.model.criterion;

import java.util.Collection;

import org.apache.commons.lang.ArrayUtils;

import com.ease.common.util.Detect;

public class Restrictions extends Detect {

	public Restrictions() {
		// cannot be instantiated
	}

	public static final String PropertyNameSuffix_Like = "_Like";

	public static final String PropertyNameSuffix_IsNull = "_IsNull";
	public static final String PropertyNameSuffix_IsNotNull = "_IsNotNull";

	public static final String PropertyNameSuffix_In = "_In";
	public static final String PropertyNameSuffix_NotIn = "_NotIn";

	public static final String PropertyNameSuffix_Lt = "_Lt";
	public static final String PropertyNameSuffix_Gt = "_Gt";
	public static final String PropertyNameSuffix_Le = "_Le";
	public static final String PropertyNameSuffix_Ge = "_Ge";
	public static final String PropertyNameSuffix_Between = "_Between";

	public static final String PropertyNameSuffix_SqlRestriction = "_SqlRestriction";

	/**
	 * Apply an "equal" constraint to the named property
	 * 
	 * @param propertyName
	 * @param value
	 * @return Criterion
	 */
	public static Criterion eq(String propertyName, Object value) {
		return new SimpleExpression(propertyName, value, "=");
	}

	/**
	 * Apply a "not equal" constraint to the named property
	 * 
	 * @param propertyName
	 * @param value
	 * @return Criterion
	 */
	public static Criterion ne(String propertyName, Object value) {
		return new SimpleExpression(propertyName, value, "<>");
	}

	/**
	 * Apply a "like" constraint to the named property
	 * 
	 * @param propertyName
	 * @param value
	 * @return Criterion
	 */
	public static Criterion like(String propertyName, String value) {
		return new SimpleExpression(propertyName, MatchMode.ANYWHERE.toMatchString(value), " like ", true);
	}

	/**
	 * Apply a "like" constraint to the named property
	 * 
	 * @param propertyName
	 * @param value
	 * @return Criterion
	 */
	public static Criterion like(String propertyName, String value, MatchMode matchMode) {
		return new SimpleExpression(propertyName, matchMode.toMatchString(value), " like ", true);
	}

	/**
	 * Apply a "greater than" constraint to the named property
	 * 
	 * @param propertyName
	 * @param value
	 * @return Criterion
	 */
	public static Criterion gt(String propertyName, Object value) {
		return new SimpleExpression(propertyName, value, ">");
	}

	/**
	 * Apply a "less than" constraint to the named property
	 * 
	 * @param propertyName
	 * @param value
	 * @return Criterion
	 */
	public static Criterion lt(String propertyName, Object value) {
		return new SimpleExpression(propertyName, value, "<");
	}

	/**
	 * Apply a "less than or equal" constraint to the named property
	 * 
	 * @param propertyName
	 * @param value
	 * @return Criterion
	 */
	public static Criterion le(String propertyName, Object value) {
		return new SimpleExpression(propertyName, value, "<=");
	}

	/**
	 * Apply a "greater than or equal" constraint to the named property
	 * 
	 * @param propertyName
	 * @param value
	 * @return Criterion
	 */
	public static Criterion ge(String propertyName, Object value) {
		return new SimpleExpression(propertyName, value, ">=");
	}

	/**
	 * Apply a "between" constraint to the named property
	 * 
	 * @param propertyName
	 * @param lo
	 *            value
	 * @param hi
	 *            value
	 * @return Criterion
	 */
	public static Criterion between(String propertyName, Object lo, Object hi) {
		return new BetweenExpression(propertyName, lo, hi);
	}

	/**
	 * Apply an "in" constraint to the named property
	 * 
	 * @param propertyName
	 * @param values
	 * @return Criterion
	 */
	public static Criterion in(String propertyName, Object[] values) {
		return new InExpression(propertyName, values);
	}

	/**
	 * Apply an "in" constraint to the named property
	 * 
	 * @param propertyName
	 * @param values
	 * @return Criterion
	 */
	public static Criterion in(String propertyName, Collection<?> values) {
		return new InExpression(propertyName, values.toArray());
	}

	/**
	 * Apply an "is null" constraint to the named property
	 * 
	 * @return Criterion
	 */
	public static Criterion isNull(String propertyName) {
		return new NullExpression(propertyName);
	}

	/**
	 * Apply an "is not null" constraint to the named property
	 * 
	 * @return Criterion
	 */
	public static Criterion isNotNull(String propertyName) {
		return new NotNullExpression(propertyName);
	}

	/**
	 * Return the conjuction of two expressions
	 * 
	 * @param lhs
	 * @param rhs
	 * @return Criterion
	 */
	public static Criterion and(Criterion lhs, Criterion rhs) {
		return new LogicalExpression(lhs, rhs, "and");
	}

	/**
	 * Return the disjuction of two expressions
	 * 
	 * @param lhs
	 * @param rhs
	 * @return Criterion
	 */
	public static Criterion or(Criterion lhs, Criterion rhs) {
		return new LogicalExpression(lhs, rhs, "or");
	}

	/**
	 * Group expressions together in a single conjunction (A and B and C...)
	 * 
	 * @return Conjunction
	 */
	public static Conjunction conjunction() {
		return new Conjunction();
	}

	/**
	 * Group expressions together in a single disjunction (A or B or C...)
	 * 
	 * @return Conjunction
	 */
	public static Disjunction disjunction() {
		return new Disjunction();
	}

	// /**
	// * Return the negation of an expression
	// *
	// * @param expression
	// * @return Criterion
	// */
	// public static Criterion not(Criterion expression) {
	// return new NotExpression(expression);
	// }
	/**
	 * Apply a constraint expressed in SQL, with the given JDBC parameters. Any occurrences of <tt>{alias}</tt> will be
	 * replaced by the table alias.
	 * 
	 * @param sql
	 * @param names
	 * @param values
	 * @return Criterion
	 */
	public static Criterion sqlRestriction(String sql, String[] names, Object[] values) {
		return new SqlCriterion(sql, names, values);
	}

	/**
	 * Apply a constraint expressed in SQL. Any occurrences of <tt>{alias}</tt> will be replaced by the table alias.
	 * 
	 * @param sql
	 * @return Criterion
	 */
	public static Criterion sqlRestriction(String sql) {
		return new SqlCriterion(sql, ArrayUtils.EMPTY_STRING_ARRAY, ArrayUtils.EMPTY_OBJECT_ARRAY);
	}

}
